package com.example.wxchatcotents;

import static de.robv.android.xposed.XposedBridge.log;
import static de.robv.android.xposed.XposedHelpers.callMethod;
import static de.robv.android.xposed.XposedHelpers.callStaticMethod;
import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.findClass;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class ChatCotentsHook implements IXposedHookLoadPackage {

	public static final String WECHAT_PACKAGE_NAME = "com.tencent.mm";

	private WechatMainDBHelper mDb;
	private Class<?> mImgClss;

	// 微信版本号
	private static String wechatVersion = "";

	private static String packageName;
	private static ClassLoader classLoader;

	@Override
	public void handleLoadPackage(LoadPackageParam lpp) throws Throwable {
		packageName = lpp.packageName;
		classLoader = lpp.classLoader;

		if (WECHAT_PACKAGE_NAME.equals(packageName)) {
			new HideModule().hide(lpp);
			if (TextUtils.isEmpty(wechatVersion)) {
				Context context = (Context) (Context) XposedHelpers.callMethod(XposedHelpers.callStaticMethod(
						XposedHelpers.findClass("android.app.ActivityThread", null), "currentActivityThread",
						new Object[0]), "getSystemContext", new Object[0]);
				String versionName = context.getPackageManager().getPackageInfo(packageName, 0).versionName;
				this.wechatVersion = versionName;
				VersionParam.init(wechatVersion);
			}

			findAndHookMethod(VersionParam.NOTIFICATION_CLASS_NAME, classLoader,
					VersionParam.NOTIFICATION_CLASS_METHOD, String.class, String.class, int.class, int.class,
					int.class, new XC_MethodHook() {
						@Override
						protected void afterHookedMethod(MethodHookParam param) throws Throwable {
							int messageType = (Integer) param.args[2];
							int tipFlag = (Integer) param.args[3];
							int what = (Integer) param.args[4];
							String content = (String) param.args[1];

							String talker = (String) param.args[0];
							String nickName = mDb.getNickname(talker);

							if (isGroupTalk(talker)) { // 如果是群聊
								String personSender = content.substring(0, content.indexOf(":"));
								nickName = nickName + "群中的" + mDb.getNickname(personSender);
								content = content.substring(content.indexOf(":") + 1);
							}

							log(nickName + "给你发了一条消息,messageType=" + messageType + ",tipFlag:" + tipFlag + ",what:"
									+ what);

							switch (messageType) {
							case 1:// 文字
								AutoReply.transSendText(new CMessage("222222", talker, "你好", "44444"), classLoader);
								log("文字消息：" + content);
								break;
							case 3:// 图片
								String imagePath = getImagePath();

								log("图片消息:" + content + ",imagePath:" + imagePath);
								break;
							case 34:// 语音
								log("语音消息:" + content);
								break;
							case 42:// 名片
								log("名片消息:" + content);
								break;
							case 43:// 小视频
								log("小视频消息:" + content);
								break;
							case 47:// 表情emoj
								String expressionUrl = getExpressionUrl(content);
								log("表情消息:" + expressionUrl);
								break;
							case 48:// 共享位置信息
								log("共享位置消息:" + content);
								break;
							case 49:// 分享的内容(带有链接)
								log("分享消息:" + content);
								break;
							case 1000:// 系统消息
								log("系统消息:" + content);
								break;
							default:
								// do nothing;
								return;
							}

						}
					});

			findAndHookConstructor(VersionParam.STORAGE_CLASS_NAME, classLoader, VersionParam.STORAGE_CLASS_METHOD,
					new XC_MethodHook() {
						@Override
						protected void afterHookedMethod(MethodHookParam param) throws Throwable {
							if (null == mDb) {
								mDb = new WechatMainDBHelper(param.args[0]);
							}
							if (null == mImgClss) {
								mImgClss = findClass(VersionParam.IMAGE_CLASS_NAME, classLoader);
							}
						}
					});

		}
	}

	private boolean isGroupTalk(String talker) {
		return talker.endsWith("@chatroom");
	}

	private String getImagePath() {
		Cursor cursor = mDb.getLastMsg();
		if (cursor == null || !cursor.moveToFirst()) {
			return null;
		}
		String imgPath = cursor.getString(cursor.getColumnIndex("imgPath"));

		String locationInSDCard = (String) callMethod(callStaticMethod(mImgClss, VersionParam.IMAGE_CLASS_METHOD1),
				VersionParam.IMAGE_CLASS_METHOD2, imgPath);

		if (TextUtils.isEmpty(locationInSDCard)) {
			return null;
		}
		return locationInSDCard.replace("emulated/0", "emulated/legacy");
	}

	private String getExpressionUrl(String content) {
		content = "http:" + content.substring(content.indexOf("//"));
		return content.substring(0, content.indexOf("\""));
	}

}
